package com.badwei.ydd.controller;

import com.alibaba.fastjson.JSON;
import com.badwei.ydd.pojo.IpAddress;
import com.badwei.ydd.pojo.Message;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: badwei
 * @Date: 2022/5/10 21:18
 * @Description:
 */
@RestController
@CrossOrigin
@Slf4j
public class MessageController {

    // 添加类变量
    private static final String CSV_FILE = System.getProperty("user.home") + "/ydd-messages.csv";
    private static final String CSV_HEADER = "id,message,info,time,ip";

    @PostConstruct
    public void init() {
        Path path = Paths.get(CSV_FILE);
        try {
            // 创建父目录（如果不存在）
            Files.createDirectories(path.getParent());
            if (!Files.exists(path)) {
                Files.write(path, (CSV_HEADER + "\n").getBytes(StandardCharsets.UTF_8),
                        StandardOpenOption.CREATE);
                log.info("初始化CSV文件成功");
            } else {
                log.info("加载CSV文件成功");
            }
        } catch (IOException e) {
            log.error("CSV文件操作失败", e);
        }
    }

    @RequestMapping("/submit/{info}")
    @CrossOrigin
    public void submit(HttpServletRequest request,
                       @RequestHeader("User-Agent") String user_agent,
                       @PathVariable("info") String info) throws IOException {

        // 解析用户信息
        UserAgent userAgent = UserAgent.parseUserAgentString(user_agent);
        String ip = this.getIpAddr(request);
        String cityName = this.ipToCityName(ip);

        // 创建消息对象
        Message message = new Message();
        message.setId(getNextId());
        message.setMessage(info);
        message.setIp(ip);
        message.setInfo("地址:" + cityName + "浏览器:" + userAgent.getBrowser().getName() + " " +
                userAgent.getBrowserVersion() + "系统:" + userAgent.getOperatingSystem().getName());

        // 设置时间
        message.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

        // 写入CSV文件
        writeToCsv(message);
        log.info("新消息已保存: {}", message);
    }

    // 获取下一个ID
    private synchronized int getNextId() throws IOException {
        List<Message> messages = readFromCsv();
        return messages.stream().mapToInt(Message::getId).max().orElse(0) + 1;
    }

    // 写入CSV文件
    private void writeToCsv(Message message) throws IOException {
        String record = String.format("%d,%s,%s,%s,%s\n",
                message.getId(),
                escapeCsv(message.getMessage()),
                escapeCsv(message.getInfo()),
                message.getTime(),
                message.getIp());

        Files.write(Paths.get(CSV_FILE), record.getBytes(StandardCharsets.UTF_8),
                StandardOpenOption.APPEND);
    }

    // 读取CSV文件
    private List<Message> readFromCsv() throws IOException {
        if (!Files.exists(Paths.get(CSV_FILE))) {
            return new ArrayList<>();
        }

        return Files.lines(Paths.get(CSV_FILE), StandardCharsets.UTF_8)
                .skip(1)
                .map(this::parseCsvLine)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    // 解析CSV行
    private Message parseCsvLine(String line) {
        try {
            String[] parts = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", -1);
            Message message = new Message();
            message.setId(Integer.parseInt(parts[0]));
            message.setMessage(unescapeCsv(parts[1]));
            message.setInfo(unescapeCsv(parts[2]));
            message.setTime(parts[3]);
            message.setIp(parts[4]);
            return message;
        } catch (Exception e) {
            log.error("解析CSV行失败: " + line, e);
            return null;
        }
    }

    // CSV特殊字符处理
    private String escapeCsv(String input) {
        if (input == null) return "";
        if (input.contains(",") || input.contains("\"") || input.contains("\n")) {
            return "\"" + input.replace("\"", "\"\"") + "\"";
        }
        return input;
    }

    private String unescapeCsv(String input) {
        if (input.startsWith("\"") && input.endsWith("\"")) {
            return input.substring(1, input.length() - 1).replace("\"\"", "\"");
        }
        return input;
    }

    // 修改queryAll方法
    @RequestMapping("/query/all")
    @CrossOrigin
    public List<Message> queryAll() throws IOException {
        List<Message> messages = readFromCsv();
        Collections.reverse(messages); // 使最新消息在前
        return messages;
    }


    public String ipToCityName(String ip) throws UnsupportedEncodingException {
        RestTemplate restTemplate=new RestTemplate();
        String url = "http://api.map.baidu.com/location/ip?ak=oNwrkbQhQNj9cKSSGUExG6LVAS4Dvryf&ip="+ ip +"&coor=bd09ll";
        IpAddress result = restTemplate.getForObject(url, IpAddress.class);
        if (ObjectUtils.isEmpty(result)){
            return null;
        }
        if (ObjectUtils.isEmpty(result.getContent())){
            return null;
        }
        if (ObjectUtils.isEmpty(result.getContent().getAddress())){
            return null;
        }
        String address = result.getContent().getAddress();
        return URLDecoder.decode(address,"UTF-8");

    }

    public String getIpAddr(HttpServletRequest request) {

        String ip = request.getHeader("x-forwarded-for");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
            //LOGGER.error("X-Real-IP:"+ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("http_client_ip");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip != null && ip.indexOf(",") != -1) {
            ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
        }
        return ip;
    }

}
